gusucode.com > VC Outlook风格的数据库浏览器 > VC Outlook风格的数据库浏览器/gusucode/Outlook/mdbViewerView.cpp
//Download by http://www.NewXing.com // mdbViewerView.cpp : implementation of the CmdbViewerView class // #include "stdafx.h" #include "mdbViewer.h" #include "mdbViewerDoc.h" #include "mdbViewerView.h" #include "MainFrm.h" #include "RecordEditorDlg.h" #include "QueryDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CmdbViewerView IMPLEMENT_DYNCREATE(CmdbViewerView, CCJListView) BEGIN_MESSAGE_MAP(CmdbViewerView, CCJListView) //{{AFX_MSG_MAP(CmdbViewerView) ON_WM_CONTEXTMENU() ON_WM_KEYUP() ON_WM_LBUTTONDBLCLK() ON_WM_MOUSEMOVE() ON_WM_CANCELMODE() ON_COMMAND(ID_FILE_PRINT_PREVIEW, OnFilePrintPreview) //}}AFX_MSG_MAP // Standard printing commands ON_COMMAND(ID_FILE_PRINT, CCJListView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CCJListView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CCJListView::OnFilePrintPreview) ON_UPDATE_COMMAND_UI(ID_LISTVIEWROW_NUM,OnUpdateListRowNum) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CmdbViewerView construction/destruction CmdbViewerView::CmdbViewerView() { m_nColsmax = 0; // max. number of columns m_nCurrentItemIndex=0; // no item by default m_nRecords=0; // no record m_IsQuery=FALSE; m_selectedRecords.SetSize(1); m_selectedRecords.SetAt(0,0); } CmdbViewerView::~CmdbViewerView() { } BOOL CmdbViewerView::PreCreateWindow(CREATESTRUCT& cs) { // default is report view cs.style |= LVS_REPORT; return CCJListView::PreCreateWindow(cs); } ///////////////////////////////////////////////////////////////////////////// // CmdbViewerView drawing void CmdbViewerView::OnDraw(CDC* pDC) { CmdbViewerDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here pDC->TextOut(100,200,"here"); } static UINT nImages[] = { IDI_ICON_RECORD, IDI_ICON_RECORDSEL }; void CmdbViewerView::OnInitialUpdate() { CCJListView::OnInitialUpdate(); // TODO: You may populate your ListView with items by directly accessing // its list control through a call to GetListCtrl(). m_pListCtrl = &GetListCtrl(); // Create the large and small image lists m_ImageList.Create (16, 16, true, 2, 1); m_ImageListNormal.Create (32, 32, true, 2, 1); HICON hIcon; for (int i =0; i < 2; ++i) { hIcon= AfxGetApp()->LoadIcon (nImages[i]); m_ImageList.Add (hIcon); m_ImageListNormal.Add (hIcon); } m_pListCtrl->SetImageList (&m_ImageList, LVSIL_SMALL); m_pListCtrl->SetImageList (&m_ImageListNormal, LVSIL_NORMAL); m_pListCtrl->SetTextColor (RGB(0,0,255)); m_Font.CreatePointFont (85, _T("Tahoma")); m_pListCtrl->SetFont (&m_Font); m_pListCtrl->SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_ONECLICKACTIVATE | LVS_EX_UNDERLINEHOT | LVS_EX_GRIDLINES); m_headerCtrl.m_bBoldFont = FALSE; } ///////////////////////////////////////////////////////////////////////////// // CmdbViewerView printing BOOL CmdbViewerView::OnPreparePrinting(CPrintInfo* pInfo) { // default preparation return DoPreparePrinting(pInfo); } void CmdbViewerView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add extra initialization before printing } void CmdbViewerView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add cleanup after printing } ///////////////////////////////////////////////////////////////////////////// // CmdbViewerView diagnostics #ifdef _DEBUG void CmdbViewerView::AssertValid() const { CCJListView::AssertValid(); } void CmdbViewerView::Dump(CDumpContext& dc) const { CCJListView::Dump(dc); } CmdbViewerDoc* CmdbViewerView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CmdbViewerDoc))); return (CmdbViewerDoc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CmdbViewerView message handlers void CmdbViewerView::OnContextMenu(CWnd* pWnd, CPoint point) { // bring up POPup menu and set up its style. // The popup menu messages will be responsed in cMainFrame class if (point.x == -1 && point.y == -1){ //keystroke invocation CRect rect; GetClientRect(rect); ClientToScreen(rect); point = rect.TopLeft(); point.Offset(5, 5); } CMenu menu; VERIFY(menu.LoadMenu(IDR_POPUP)); CMenu* pPopup = menu.GetSubMenu(0); ASSERT(pPopup != NULL); CWnd* pWndPopupOwner = this; while (pWndPopupOwner->GetStyle() & WS_CHILD) pWndPopupOwner = pWndPopupOwner->GetParent(); pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, pWndPopupOwner); } void CmdbViewerView::ClearListView() { if(m_pListCtrl!=NULL) ASSERT(m_pListCtrl); m_pListCtrl->DeleteAllItems(); } void CmdbViewerView::ShowDBTable() { ProcessUpdating(_T("Loading recordset ...")); // suppose a record set has been opened CmdbViewerDoc* pDoc = GetDocument(); if(m_pListCtrl!=NULL) ClearListView(); pDoc->LoadRecordset(); // After call for pDoc->LoadRecordset, // the pDoc->m_pRecordset is renewed // and therefore you must update your local variables associated // with pDoc->m_pRecordset, for example m_pSet. m_pSet=pDoc->GetRecordSet(); m_TableName=pDoc->GetTableName(); ProcessUpdating(_T("Updating list view ...")); if(m_pSet!= NULL) { ASSERT_VALID(m_pSet); BeginWaitCursor(); m_nFields = (int) m_pSet->GetFieldCount(); int nColSize =80; CString fieldname; CDaoFieldInfo fi; // build columns first LV_COLUMN lvCol; lvCol.mask = LVCF_FMT|LVCF_WIDTH|LVCF_TEXT|LVCF_SUBITEM; lvCol.cx = nColSize; lvCol.fmt = LVCFMT_LEFT; for(int i = 0; i < m_nFields; i++) { m_pSet->GetFieldInfo(i, fi); fieldname=fi.m_strName; // Insert the ith column into the list control lvCol.iSubItem = i; lvCol.pszText = (char*)(LPCTSTR)fieldname; if(i<m_nColsmax) { m_pListCtrl->SetColumn(i, &lvCol); } else m_pListCtrl->InsertColumn(i, &lvCol); } if(m_nColsmax-m_nFields>0) { for(i = m_nFields; i <m_nColsmax; i++) { lvCol.iSubItem = i; lvCol.pszText = (char*)(LPCTSTR)(_T("")); lvCol.cx = 0; // set this column width as 0 m_pListCtrl->SetColumn(i, &lvCol); } } if(m_nColsmax<m_nFields) m_nColsmax=m_nFields; // insert items LV_ITEM lvi; lvi.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_STATE; lvi.stateMask = LVIS_STATEIMAGEMASK; lvi.state = INDEXTOSTATEIMAGEMASK(1); lvi.iSubItem = 0; lvi.iImage = 0; // use icon IDI_ICON_RECORD COleVariant var; CString str; for (int j=0;! m_pSet->IsEOF () ;j++) { lvi.iItem = j; var = m_pSet->GetFieldValue(0); str=formatedValue(var); lvi.pszText = (char*)(LPCTSTR)str; if (m_pListCtrl->InsertItem(&lvi) != -1) { for(i = 1; i < m_nFields; i++) { var = m_pSet->GetFieldValue(i); str=formatedValue(var); m_pListCtrl->SetItemText(j, i, str); } // loop on column index i } m_pSet->MoveNext(); } // loop on row index j EndWaitCursor(); // When loading finished, m_pSet points to the last record, which can // be used to validate the record count m_pSet->MoveLast(); m_nRecords=m_pSet->GetAbsolutePosition()+1; } else { AfxMessageBox(_T("This recordset is not properly opened")); return; } m_IsQuery=FALSE; } CString CmdbViewerView::formatedValue(COleVariant var) { CString str; switch (var.vt) { case VT_BSTR: str = (LPCSTR) var.bstrVal; // narrow characters in DAO break; case VT_I2: str.Format("%d", (int) var.iVal); break; case VT_I4: str.Format("%d", var.lVal); break; case VT_R4: str.Format("%10.2f", (double) var.fltVal); break; case VT_R8: str.Format("%10.2f", var.dblVal); break; case VT_CY: str = COleCurrency(var).Format(); break; case VT_DATE: str = COleDateTime(var).Format(); break; case VT_BOOL: str = (var.boolVal == 0) ? "FALSE" : "TRUE"; break; case VT_NULL: str = "----"; break; default: str.Format("Unk type %d\n", var.vt); TRACE("Unknown type %d\n", var.vt); } return str; } void CmdbViewerView::OnUpdateListRowNum(CCmdUI* pCmdUI) { CString strRowInfo; strRowInfo.Format(_T("Record: %d of %d"), m_nCurrentItemIndex+1, m_nRecords); pCmdUI->SetText(strRowInfo); } void CmdbViewerView::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) { // Because the GetSelectedItemIndex() is used, this method // also functions for KeyDown, Home, End,PageUp,PageDown // The benefit of this is we do not need to catch all the messages // while a reasonable speed is reserved. SetSelectedItemIndex(); CCJListView::OnKeyUp(nChar, nRepCnt, nFlags); } void CmdbViewerView::SetSelectedItemIndex() { m_pListCtrl = &GetListCtrl(); ASSERT(m_pListCtrl != NULL); POSITION pos = m_pListCtrl->GetFirstSelectedItemPosition(); if (pos == NULL) { TRACE0("No items were selected!\n"); } else { m_nCurrentItemIndex=m_pListCtrl->GetNextSelectedItem(pos); } if(m_IsQuery&&(m_nCurrentItemIndex>=0)&&(m_nCurrentItemIndex<=m_selectedRecords.GetUpperBound())) m_nCurrentItemIndex=m_selectedRecords.GetAt(m_nCurrentItemIndex); } void CmdbViewerView::OnLButtonDblClk(UINT nFlags, CPoint point) { // Navigate from here Navigation(); CCJListView::OnLButtonDblClk(nFlags, point); } BOOL CmdbViewerView::UpdateListView(int nFlag, CStringArray *fieldValues) { // nFlag=1 add an item at last // nFlag=2 modify an item at current position // nFlag=3 delete an item at current position CmdbViewerDoc* pDoc = GetDocument(); m_pSet=pDoc->GetRecordSet(); m_pListCtrl = &GetListCtrl(); if(nFlag==1) { // to validate record count if (!m_pSet->IsBOF()) { m_pSet->MoveLast(); } } int nRowIdx=m_pSet->GetAbsolutePosition(); AfxMessageBox(pDoc->IntoStr(nRowIdx)); /* if((nFlag==3)&&(nRowIdx>=0)) { // delete the current item from the m_pListCtrl->DeleteItem(nRowIdx); return TRUE; } */ if((nFlag==3)&&(m_nCurrentItemIndex>=0)) { // delete the current item from the m_pListCtrl->DeleteItem(m_nCurrentItemIndex); return TRUE; } LV_ITEM lvi; lvi.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_STATE; lvi.iItem = nRowIdx; lvi.iSubItem = 0; lvi.iImage = NULL; // use icon IDI_ICON_OUTLOOK lvi.stateMask = LVIS_STATEIMAGEMASK; lvi.state = INDEXTOSTATEIMAGEMASK(1); lvi.pszText = (char*)(LPCTSTR)(fieldValues->GetAt(0)); if (m_pListCtrl->InsertItem(&lvi) != -1) { for(int i = 1; i < m_nFields; i++) { m_pListCtrl->SetItemText(nRowIdx, i, fieldValues->GetAt(i)); } // loop on column index i m_pListCtrl->Update(nRowIdx); return TRUE; } else return FALSE; } void CmdbViewerView::OnMouseMove(UINT nFlags, CPoint point) { m_pListCtrl = &GetListCtrl(); ASSERT(m_pListCtrl != NULL); if(m_pListCtrl->GetItemCount()==0) { return; // No record in the recordset } m_nCurrentItemIndex=m_pListCtrl->HitTest(point); if(m_IsQuery&&(m_nCurrentItemIndex>=0)&&(m_nCurrentItemIndex<=m_selectedRecords.GetUpperBound())) m_nCurrentItemIndex=m_selectedRecords.GetAt(m_nCurrentItemIndex); CCJListView::OnMouseMove(nFlags, point); } void CmdbViewerView::OnCancelMode() { CCJListView::OnCancelMode(); // TODO: Add your message handler code here } void CmdbViewerView::Navigation() { if(m_IsQuery) return; // no navigation if the list view is at query state m_pListCtrl = &GetListCtrl(); ASSERT(m_pListCtrl != NULL); if(m_pListCtrl->GetItemCount()==0) { return; // No record in the recordset // One thing could be done is to add a new record // You can implement this } if(m_nRecords>0) { CmdbViewerDoc* pDoc = GetDocument(); m_pSet=pDoc->GetRecordSet(); if(m_nCurrentItemIndex<0) m_nCurrentItemIndex=0; m_pSet->SetAbsolutePosition(m_nCurrentItemIndex); // point to current record CRecordEditorDlg* REDdlg=new CRecordEditorDlg(this); CStringArray fieldValues; CStringArray fieldNames; fieldValues.SetSize(40); fieldNames.SetSize(40); for (int i=0;i<40;i++) { fieldValues[i]=_T(""); fieldNames[i]=_T(""); } COleVariant var; CDaoFieldInfo fi; for (i = 0; i < m_nFields; i++) { var = m_pSet->GetFieldValue(i); m_pSet->GetFieldInfo(i, fi); fieldNames[i] = fi.m_strName; fieldValues[i]=formatedValue(var); } // Loop on i REDdlg->m_fieldValue1 = fieldValues.GetAt(0); REDdlg->m_fieldValue2 = fieldValues.GetAt(1); REDdlg->m_fieldValue3 = fieldValues.GetAt(2); REDdlg->m_fieldValue4 = fieldValues.GetAt(3); REDdlg->m_fieldValue5 = fieldValues.GetAt(4); REDdlg->m_fieldValue6 = fieldValues.GetAt(5); REDdlg->m_fieldValue7 = fieldValues.GetAt(6); REDdlg->m_fieldValue8 = fieldValues.GetAt(7); REDdlg->m_fieldName1 = fieldNames.GetAt(0); REDdlg->m_fieldName2 = fieldNames.GetAt(1); REDdlg->m_fieldName3 = fieldNames.GetAt(2); REDdlg->m_fieldName4 = fieldNames.GetAt(3); REDdlg->m_fieldName5 = fieldNames.GetAt(4); REDdlg->m_fieldName6 = fieldNames.GetAt(5); REDdlg->m_fieldName7 = fieldNames.GetAt(6); REDdlg->m_fieldName8 = fieldNames.GetAt(7); for (i=0;i<m_nFields; i++) { REDdlg->PassFieldNames(i,fieldNames[i]); REDdlg->PassFieldValues(i,fieldValues[i]); } m_pSet->SetAbsolutePosition(m_nCurrentItemIndex); // point to current record if(REDdlg->DoModal()==IDOK) { // } } // if not the title row } void CmdbViewerView::Enquery() { m_pListCtrl = &GetListCtrl(); ASSERT(m_pListCtrl != NULL); if(m_pListCtrl->GetItemCount()==0) { return; } if(m_nRecords>0) { CmdbViewerDoc* pDoc = GetDocument(); if(m_nCurrentItemIndex<0) m_nCurrentItemIndex=0; m_pSet=pDoc->GetRecordSet(); CQueryDlg* Qdlg=new CQueryDlg(this); if(Qdlg->DoModal()==IDOK) { BeginWaitCursor(); m_queryString=Qdlg->m_queryString; m_queryField=Qdlg->GetqueryFieldName(); ExecuteQuery(); EndWaitCursor(); CMainFrame* pFrame=(CMainFrame*) AfxGetApp()->m_pMainWnd; CString str; str.Format(_T("Query : [%s] %s"), m_queryField, m_queryString); pFrame->AddNewQuery(str); } } // if not the title row } void CmdbViewerView::ExecuteQuery() { if(m_queryString.IsEmpty()) { m_IsQuery=FALSE; return; } else m_IsQuery=TRUE; ProcessUpdating(_T("Loading recordset ...")); // suppose a record set has been opened CmdbViewerDoc* pDoc = GetDocument(); if(m_pListCtrl!=NULL) ClearListView(); pDoc->LoadRecordset(); m_pSet=pDoc->GetRecordSet(); m_TableName=pDoc->GetTableName(); ProcessUpdating(_T("Searching and updating list view ...")); int queryFieldIndex=0; if(m_pSet!= NULL) { ASSERT_VALID(m_pSet); m_nFields = (int) m_pSet->GetFieldCount(); int nColSize =80; CString fieldname; CDaoFieldInfo fi; // build columns first LV_COLUMN lvCol; lvCol.mask = LVCF_FMT|LVCF_WIDTH|LVCF_TEXT|LVCF_SUBITEM; lvCol.cx = nColSize; lvCol.fmt = LVCFMT_LEFT; for(int i = 0; i < m_nFields; i++) { m_pSet->GetFieldInfo(i, fi); fieldname=fi.m_strName; if(fieldname.Compare(m_queryField)==0) queryFieldIndex=i; // Insert the ith column into the list control lvCol.iSubItem = i; lvCol.pszText = (char*)(LPCTSTR)fieldname; if(i<m_nColsmax) { m_pListCtrl->SetColumn(i, &lvCol); } else m_pListCtrl->InsertColumn(i, &lvCol); } if(m_nColsmax-m_nFields>0) { for(i = m_nFields; i <m_nColsmax; i++) { lvCol.iSubItem = i; lvCol.pszText = (char*)(LPCTSTR)(_T("")); lvCol.cx = 0; // set this column width as 0 m_pListCtrl->SetColumn(i, &lvCol); } } if(m_nColsmax<m_nFields) m_nColsmax=m_nFields; // insert items LV_ITEM lvi; lvi.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_STATE; lvi.stateMask = LVIS_STATEIMAGEMASK; lvi.state = INDEXTOSTATEIMAGEMASK(1); lvi.iSubItem = 0; lvi.iImage = 1; // use icon IDI_ICON_RECORDSEL COleVariant var; CString str,str1,str2; int selectedItems=0; for (int j=0;! m_pSet->IsEOF () ;j++) { var = m_pSet->GetFieldValue(queryFieldIndex); str1=formatedValue(var); str1.MakeLower(); str2=m_queryString; str2.MakeLower(); if(str1.Find(str2)>=0) { lvi.iItem = selectedItems; var = m_pSet->GetFieldValue(0); str=formatedValue(var); lvi.pszText = (char*)(LPCTSTR)str; if (m_pListCtrl->InsertItem(&lvi) != -1) { for(i = 1; i < m_nFields; i++) { var = m_pSet->GetFieldValue(i); str=formatedValue(var); m_pListCtrl->SetItemText(selectedItems, i, str); } // loop on column index i } if(m_IsQuery) m_selectedRecords.SetAtGrow(selectedItems,j); selectedItems++; } m_pSet->MoveNext(); } // loop on row index j m_selectedRecords.FreeExtra(); } else { AfxMessageBox(_T("This recordset is not properly opened")); return; } } void CmdbViewerView::ProcessUpdating(CString strProcess) { CMainFrame* pFrame=(CMainFrame*) AfxGetApp()->m_pMainWnd; CStatusBar* pStatus=&pFrame->m_wndStatusBar; if(pStatus) { pStatus->SetPaneText(pStatus->CommandToIndex(ID_LISTVIEWROW_NUM),strProcess); } } void CmdbViewerView::OnFilePrintPreview() { // TODO: Add your command handler code here }